package com.kotlin.lib.coroutines

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import okhttp3.*
import java.io.IOException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

data class HttpResponse<T>(val code: Int, val message: String, val data: T)

fun log(content: String?) {
    println("${Thread.currentThread().name} >>$content")
}

fun main() = runBlocking<Unit> {
    val url = "http://api.yhouse.com/config/init"
    val client = OkHttpClient()
/*    val job = launch(Dispatchers.IO*//* + SupervisorJob()*//*) {
        log("request:")
        val abc = "hello"
        client.newCall(Request.Builder().url(url).get().build()).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                log("onFailure.  ")
                launch(Dispatchers.Default) {
                    log("${call.request().url} , ${e.message}")
                }
                cancel()
            }

            override fun onResponse(call: Call, response: Response) {
                log("onResponse. ${response.isSuccessful}")
                response.use {
                    if (response.isSuccessful) {
                        val utf8 = response.body?.source()?.readByteString()?.utf8()
                        utf8?.let {
                            log("let. start new coroutines  ${coroutineContext[Job]?.isActive}")
                            launch(Dispatchers.Default) {
                                log(utf8)
                            }
                        }
                        log("statusCode=${utf8 == null}")
                    } else {
                        log("statusCode=${response.code}")
                    }
                }
                cancel()
            }
        })
        delay(20000)
    }*/
    try {
        val await = client.newCall(Request.Builder().url(url).get().build()).await()
        println("await:::$await")
    } catch (e: Exception) {
        log(e.message)
    }
//    val request = request()
//    log("sync>>" + request.body?.string())
//    job.join()
    println("job done")
}

suspend fun Call.await(): String? = suspendCoroutine {
    enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            it.resumeWithException(e)
        }

        override fun onResponse(call: Call, response: Response) {
            if (response.isSuccessful) {
                it.resume(response.body?.string())
            } else {
                it.resumeWithException(IllegalArgumentException("code=$response"))
            }
        }
    })
}

suspend fun request() = coroutineScope {
    val url = "http://api.yhouse.com/config/init"
    val client = OkHttpClient()
    val execute = async(Dispatchers.IO) {
        client.newCall(Request.Builder().url(url).get().build()).execute()
    }

    execute.await()
}

